/*
 * Copyright (C) 2005 Johan Maasing johan at zoom.nu Licensed under the Apache
 * License, Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
 * or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package nu.zoom.swing.desktop.plugin.portunis.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Iterator;

import nu.zoom.swing.desktop.plugin.portunis.KeyStoreHandler;
import nu.zoom.swing.desktop.plugin.portunis.KeyStoreType;
import nu.zoom.swing.desktop.plugin.portunis.KeyStoreWrapper;
import nu.zoom.swing.desktop.plugin.portunis.ZoomKeyStore;

/**
 * @see nu.zoom.swing.desktop.plugin.portunis.KeyStoreHandler
 * @version $Revision: 1.2 $
 * @author $Author: johan $
 */
public class KeyStoreHandlerImpl implements KeyStoreHandler
{

	private ArrayList<KeyStoreWrapperImpl> keyStores = new ArrayList<KeyStoreWrapperImpl>();

	public KeyStoreHandlerImpl() {
		super();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see nu.zoom.swing.desktop.plugin.portunis.crypto.KeystoreFactory#getkeyStore(java.lang.String)
	 */
    @Override
	public synchronized KeyStore createKeyStore(String dn)
	{
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see nu.zoom.swing.desktop.plugin.portunis.crypto.KeystoreFactory#loadKeystore(java.io.File)
	 */
    @Override
	public synchronized KeyStoreWrapper loadKeyStore(File filename,
			KeyStoreType type, char[] password) throws KeyStoreException,
			NoSuchAlgorithmException, CertificateException,
			FileNotFoundException, IOException
	{
		KeyStore realKeyStore = KeyStore.getInstance(type.getType());
		ZoomKeyStoreImpl keyStore = new ZoomKeyStoreImpl(realKeyStore);
		KeyStoreWrapperImpl wrapper;
		if (password.length == 0) {
			keyStore.load(new FileInputStream(filename), null);
		} else {
			keyStore.load(new FileInputStream(filename), password);
		}
		wrapper = null;
		boolean alreadyLoaded = false;
		for (Iterator<KeyStoreWrapperImpl> storeIter = keyStores.iterator(); (storeIter.hasNext() && !alreadyLoaded);) {
			KeyStoreWrapperImpl wrapperInStore = storeIter
					.next();
			if (filename.equals(wrapperInStore.getFile())) {
				alreadyLoaded = true;
				wrapperInStore.setKeyStore(keyStore);
				wrapper = wrapperInStore;
			}
		}
		if (!alreadyLoaded) {
			wrapper = new KeyStoreWrapperImpl();
			wrapper.setFile(filename);
			wrapper.setKeyStore(keyStore);
			wrapper.setType(type);
			keyStores.add(wrapper);
		}
		return wrapper;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see nu.zoom.swing.desktop.plugin.portunis.crypto.KeystoreFactory#getLoadedKeystores()
	 */
    @Override
	public synchronized KeyStoreWrapper[] getLoadedKeyStores()
	{
		return keyStores.toArray(new KeyStoreWrapper[keyStores.size()]);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see nu.zoom.swing.desktop.plugin.portunis.crypto.KeyStoreHandler#saveKeyStore(nu.zoom.swing.desktop.plugin.portunis.crypto.KeyStoreWrapper)
	 */
    @Override
	public void saveKeyStore(KeyStoreWrapper wrapper, char[] password)
			throws KeyStoreException, NoSuchAlgorithmException,
			CertificateException, IOException
	{
		FileOutputStream outs = new FileOutputStream(wrapper.getFile());
		wrapper.getKeyStore().store(outs, password);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see nu.zoom.swing.desktop.plugin.portunis.crypto.KeyStoreHandler#saveKeyStoreAs(nu.zoom.swing.desktop.plugin.portunis.crypto.KeyStoreWrapper,
	 *      java.io.File)
	 */
    @Override
	public void saveKeyStoreAs(KeyStoreWrapper wrapper, File newFileName,
			char[] password) throws KeyStoreException,
			NoSuchAlgorithmException, CertificateException, IOException
	{
		FileOutputStream outs = new FileOutputStream(newFileName);
		wrapper.getKeyStore().store(outs, password);
	}

	public static class KeyStoreWrapperImpl implements KeyStoreWrapper
	{

		private KeyStoreType type;
		private File file;
		private ZoomKeyStore keyStore;

		/*
		 * (non-Javadoc)
		 * 
		 * @see nu.zoom.swing.desktop.plugin.portunis.crypto.KeyStoreWrapper#getType()
		 */
        @Override
		public KeyStoreType getType()
		{
			return type;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see nu.zoom.swing.desktop.plugin.portunis.crypto.KeyStoreWrapper#getFile()
		 */
        @Override
		public File getFile()
		{
			return file;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see nu.zoom.swing.desktop.plugin.portunis.crypto.KeyStoreWrapper#getKeyStore()
		 */
        @Override
		public ZoomKeyStore getKeyStore()
		{
			return keyStore;
		}

		void setFile(File file)
		{
			this.file = file;
		}

		void setKeyStore(ZoomKeyStore store)
		{
			this.keyStore = store;
		}

		void setType(KeyStoreType type)
		{
			this.type = type;
		}
	}
}
